# qt4 modules
from PyQt4 import QtCore, QtGui, uic
# python modeuls
import sys, os.path
# python imaging modules
import ImageQt, ImageDraw, ImageFont, Image


# Load icons
icon_resource_file = os.path.join(os.path.dirname(__file__),"icons.rcc")
QtCore.QResource.registerResource(icon_resource_file)


# Load UI
(FontPreviewForm, FontPreviewBase) = uic.loadUiType(os.path.join(os.path.dirname(__file__), "fontpreview.ui"))


def requiresRedraw(func):
	"""Wrapper for methods which require the widget to redraw."""

	def wrapper(self, *args, **kargs):
		result = func(self, *args, **kargs)
		self.update()
		return result
	return wrapper


class FontPreviewWidget(FontPreviewBase):
	"""Font preview widget."""

	def __init__(self, parent=0, *args):
		"""Init font preview widget."""

		FontPreviewBase.__init__(self)
		FontPreviewForm().setupUi(self)
		self.setupUi()

		# Default values
		self.fontFile = None
		self.sampleText = "Sample Text"
		self.sampleSize = 20

	def setupUi(self):
		"""Setup UI elements."""

		self.fontSizeInput = self.findChild(QtGui.QSpinBox, "fontSizeInput")
		self.connect(self.fontSizeInput, QtCore.SIGNAL("valueChanged (int)"), self._internal_setSampleSize)
		self.fontNameLabel = self.findChild(QtGui.QLabel, "fontName")

	@property
	def fontName(self):
		"""@return font name (not the font file name)."""

		if self.fontFile is None:
			return u"No font set"

		return ", ".join(ImageFont.truetype(self.fontFile, self.sampleSize).getname())

	@requiresRedraw
	def setFontFile(self, font):
		"""Set preview font."""

		self._font_file = font
		try:
			self.fontNameLabel.setText(self.fontName)
		except:
			self._font_file = None
			self.fontNameLabel.setText(u"Error loading font %s " % font)

	def getFontFile(self):
		"""Get preview font."""

		return self._font_file

	fontFile = property(getFontFile, setFontFile)

	@requiresRedraw
	def setSampleText(self, text):
		"""Set text to be used in preview."""

		self._text = text

	def getSampleText(self):
		"""Get text to be used in preview."""

		return self._text

	sampleText = property(getSampleText, setSampleText)

	@requiresRedraw
	def _internal_setSampleSize(self, size):
		"""Set sample size (without updating spinbox editor)."""

		self._sample_size = size

	def setSampleSize(self, size):
		"""Set sample size and update spinbox editor."""

		self._internal_setSampleSize(size)
		self.fontSizeInput.setValue(size)

	def getSampleSize(self):
		"""Get sample font size."""

		return self._sample_size

	sampleSize = property(getSampleSize, setSampleSize)

	def drawSampleText(self, size):
		"""Draw sample text and return a QImage.

		@param size size of image to draw text on
		"""

		font = ImageFont.truetype(self.fontFile, self.sampleSize)
		image = Image.new("RGBA", (size.width(), size.height()))
		draw = ImageDraw.Draw(image)
		draw.setink("black")
		draw.text((0, 0), self.sampleText, font=font)
		return ImageQt.ImageQt(image)

	def sizeHint(self):
		"""See QT4 Reference."""

		return QtCore.QSize(*self.getSampleTextSize())

	def getSampleTextSize(self):
		"""Get size of rendered sample text using python imaging library."""

		try:
			font = ImageFont.truetype(self.fontFile, self.sampleSize)
		except TypeError:
			return (10,10)

		#return font.getsize(self.sampleText)
		(width, height) = font.getsize(self.sampleText)
		#return (10,10)
		return (min(400, width), height)

	def paintEvent(self, event):
		"""See QT4 Reference."""

		if self.fontFile is None: # No font to render
			return

		painter = QtGui.QPainter(self)
		# Center drawing coordinates
		painter.translate(self.width() / 2, self.height() / 2)

		# Draw font preview on a buffer
		sample_render_size = QtCore.QSize(*self.getSampleTextSize())
		sample = self.drawSampleText(sample_render_size)

		# Paint preview buffer to widget
		painter.translate(- sample_render_size.width() / 2, - sample_render_size.height() / 2)
		painter.drawImage(0,0,sample)


# Test
if __name__ == "__main__":

	app = QtGui.QApplication(sys.argv)
	font_preview = FontPreviewWidget()
	font_preview.fontFile = "/home/download/Fonts pack/Fonts/A033000D.TTF"
	font_preview.sampleText = "Sample text"
	font_preview.sampleSize = 50
	font_preview.show()
	sys.exit(app.exec_())
